#include <iostream>

using namespace std;

class Date//日期类不需要定义析构，拷贝构造，赋值重载
{
    friend ostream& operator<<(ostream& out, const Date& d);
    friend istream& operator>>(istream& in, Date& d); 
public:
    //构造函数
    Date(int year = 1, int month = 1, int day = 1)
    {
        _year = year;
        _month = month;
        _day = day;

        if(!CheckDate())
        {
            cout << "非法日期:";
            Print();
        }
    }
    int GetYear()
    {
        return _year;
    }
    //拷贝构造函数
    // Date(const Date& d1)//可不写
    // {
    //     _year = d1._year;
    //     _month = d1._month;
    //     _day = d1._day;
    // }
    //析构函数
    ~Date()//可不写
    {
        _year = 0;
        _month = 0;
        _day = 0;
    }
    void Print()
    {
        cout << _year << "/" << _month << "/" << _day << endl;
    }
    bool CheckDate() const;
    // 获取某年某月的天数
    int GetMonthDay(int year, int month) const//类内函数默认为内联函数,频繁使用的小函数建议内联直接展开
    {
        static int MonthDayGetArray[13] = {-1,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if(month == 2 && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0))
        {
            return 29;
        }
        return MonthDayGetArray[month];
    }
    //运算符重载
    //日期 == 日期
    bool operator==(const Date& d) const;
    // !=
    bool operator!=(const Date& d) const;      
    // >
    bool operator > (const Date& d) const;
    // >=
    bool operator >= (const Date& d) const;
    // <
    bool operator < (const Date& d) const;
    // <=
    bool operator <= (const Date& d) const;
    //取地址运算符为默认成员函数，一般不需要自己实现
    Date* operator & ()
    {
        return this;
    }
    const Date* operator & () const
    {
        return this;
    }

    //赋值运算符重载
    //日期+=天数
    Date& operator+=(int day);
    //日期+天数
    Date operator+(int day) const;
    //日期-天数
    Date operator-(int day) const;
    //日期-=天数
    Date& operator-=(int day);
    //前置++
    Date& operator++();
    //后置++（默认给一个int形参与前置++构成函数重载来区分
    Date operator++(int);
    //前置--
    Date& operator--();
    //后置--（默认给一个int形参与前置--构成函数重载来区分
    Date operator--(int);
    // 日期-日期 返回天数
    int operator-(const Date& d) const;


private:
    int _year;
    int _month;
    int _day;
};

ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);
